भाग 8 - योजनांचा परिचय

संदर्भ

आम्ही येथे एक वस्तू सादर करीत आहोत जी औद्योगिक फेडरेटेड लर्निंग: द प्लॅनच्या (plan) प्रमाणात महत्त्वाची आहे. हे नाटकीयरित्या बँडविड्थ वापर कमी करते, एसिन्क्रॉनस योजनांना परवानगी देते आणि दूरस्थ उपकरणांना अधिक स्वायत्तता देते. योजनेची मूलभूत संकल्पना पेपर Towards Federated Learning at Scale: System Design मध्ये आढळू शकते परंतु PySyft लायब्ररीत आपल्या गरजा भागवल्या आहेत.

योजनेचा उद्देश एखाद्या फंक्शनप्रमाणेच torch ऑपरेशन्सचा क्रम संग्रहित करण्याचा होता, परंतु तो ऑपरेशनचा हा क्रम दुर्गम कामगारांना पाठविण्यास आणि त्यास संदर्भ ठेवण्यास अनुमती देतो. अशाप्रकारे दूरस्थपणे या क्रमाची गणना करणे $n$ काही रिमोट इनपुटवरील ऑपरेशन्स पाठविण्याऐवजी पॉईंटर्सद्वारे संदर्भित $n$ आपल्याला आता आवश्यक असलेले संदेश आणि योजनेच्या संदर्भात एक संदेश पाठविण्यासाठी आवश्यक आहे. आपण आपल्या फंक्शनसह टेन्सर देखील प्रदान करू शकता (ज्यास आम्ही विस्तारित कार्यक्षमतेसाठी state tensors म्हणतो). एकतर आपण पाठवू शकता असे फंक्शन किंवा दूरस्थपणे पाठविल्या जाणार्‍या आणि अंमलात आणल्या जाणार्‍या वर्गाप्रमाणे ही योजना पाहिली जाऊ शकते. म्हणूनच, उच्च स्तरावरील वापरकर्त्यांसाठी, नियोजन करण्याची कल्पना अदृश्य होते आणि त्या जागी जादूची वैशिष्ट्ये घेतली जातात ज्यामुळे अनियंत्रित कार्य अनुक्रमित torch कार्यांसह दूरस्थ कामगारांना पाठविण्याची परवानगी मिळते.

एक गोष्ट लक्षात घेण्यासारखी आहे की आपण ज्या योजनांचे रुपांतर करू शकता अशा फंक्शन्सचा वर्ग सध्या केवळ hooked torch च्या अनुक्रमांपुरता मर्यादित आहे. आपण लवकरच वर्कआउंड करण्याचे कार्य करत असलो तरीही if, for आणि while स्टेटमेन्ट यासारख्या विशिष्ट लॉजिकल स्ट्रक्चर्समध्ये हे समाविष्ट नाही. तंतोतंत, आपण ते वापरू शकता परंतु आपण घेतलेला लॉजिकल मार्ग (उदाहरणार्थ पहिले if ला चुकीच आणि 5 loops ला for मध्ये) आपल्या योजनेच्या पहिल्या गणनामध्ये सर्वांसाठी ठेवलेला मार्ग असेल. पुढील मोजणी, जी आपल्याला बर्‍याच प्रकरणांमध्ये टाळायची आहे.

लेखक:

अनुवादक/संपादक:

आयात आणि मॉडेल वैशिष्ट्य

प्रथम अधिकृत आयात.


In [ ]:
import torch
import torch.nn as nn
import torch.nn.functional as F

आणि PySyft ला विशिष्ट, एका महत्त्वपूर्ण नोटसहः स्थानिक कामगार ग्राहक नसावेत. ग्राहक नसलेले कामगार आयटम साठवू शकतात आणि योजना चालविण्यासाठी आम्हाला या क्षमतेची आवश्यकता आहे.


In [ ]:
import syft as sy  # import the Pysyft library
hook = sy.TorchHook(torch)  # hook PyTorch ie add extra functionalities 

# IMPORTANT: Local worker should not be a client worker
hook.local_worker.is_client_worker = False


server = hook.local_worker

आपण संदर्भ लेखात प्रदान केलेल्या गृहितकांशी सुसंगत राहण्यासाठी दूरस्थ कामगार किंवा उपकरणे(devices), परिभाषित करतो. आपण त्यांना काही डेटा प्रदान करतो.


In [ ]:
x11 = torch.tensor([-1, 2.]).tag('input_data')
x12 = torch.tensor([1, -2.]).tag('input_data2')
x21 = torch.tensor([-1, 2.]).tag('input_data')
x22 = torch.tensor([1, -2.]).tag('input_data2')

device_1 = sy.VirtualWorker(hook, id="device_1", data=(x11, x12)) 
device_2 = sy.VirtualWorker(hook, id="device_2", data=(x21, x22))
devices = device_1, device_2

मूळ उदाहरण

चला आपण एखाद्या योजनेत रूपांतरित करायचे फंक्शन परिभाषित करू. असे करण्यासाठी हे फंक्शन डेफिनेशनच्या वर डेकोरेटर घालण्याइतके सोपे आहे!


In [ ]:
@sy.func2plan()
def plan_double_abs(x):
    x = x + x
    x = torch.abs(x)
    return x

चला आता तपासूया, आपली आता एक योजना आहे!


In [ ]:
plan_double_abs

योजना वापरण्यासाठी आपल्याला दोन गोष्टी आवश्यक आहेतः एक योजना तयार करणे (फंक्शनमध्ये उपस्थित असलेल्या क्रियांच्या क्रमाची नोंदणी करा ) आणि त्यास कामगार / साधनाकडे पाठवणे. सुदैवाने आपण हे अगदी सहजपणे करू शकता!

योजना तयार करुयात

योजना तयार करण्यासाठी आपल्याला त्यास फक्त काही डेटावर कॉल करण्याची आवश्यकता आहे.

चला प्रथम काही दूरस्थ डेटाचा संदर्भ घेऊ: एक विनंती नेटवर्कवर पाठविली जाते आणि संदर्भ पॉईंटर परत केला जातो.


In [ ]:
pointer_to_data = device_1.search('input_data')[0]
pointer_to_data

आपण योजना सांगल्यास ते डिव्हाइस स्थानावर दूरस्थपणे अंमलात आणले जावे location: device_1 ... आपल्याला एक त्रुटी मिळेल कारण योजना अद्याप तयार केलेली नव्हती.


In [ ]:
plan_double_abs.is_built

In [ ]:
# Sending non-built Plan will fail
try:
    plan_double_abs.send(device_1)
except RuntimeError as error:
    print(error)

एक योजना तयार करण्यासाठी आपल्याला योजनेवर build कॉल करण्याची आवश्यकता आहे आणि योजनेची अंमलबजावणी करण्यासाठी आवश्यक तर्कशास्त्र पास करणे आवश्यक आहे (काही डेटा a.k.a). जेव्हा एखादी योजना तयार केली जाते तेव्हा सर्व कमांड स्थानिक कामगार क्रमाने अंमलात आणतात आणि योजनेद्वारे ते कॅप्चर करतात आणि त्या actions विशेषतामध्ये संग्रहित करतात!


In [ ]:
plan_double_abs.build(torch.tensor([1., -2.]))

In [ ]:
plan_double_abs.is_built

आपण आता योजना पाठविण्याचा प्रयत्न केल्यास ते कार्य करते!


In [ ]:
# This cell is executed successfully
pointer_plan = plan_double_abs.send(device_1)
pointer_plan

तोपर्यंत टेन्सरसह, आम्हाला पाठविलेल्या ऑब्जेक्टसाठी एक पॉईंटर मिळेल. येथे त्याला फक्त PointerPlan म्हणतात.

लक्षात ठेवण्याची एक महत्त्वाची गोष्ट म्हणजे जेव्हा एखादी योजना तयार केली जाते, तेव्हा आम्ही पुढे आयडी (एस) प्री-सेट करतो, जिथे निकाल संग्रहित केला जावा. आभासी निकालाच्या संदर्भात आणि दूरस्थ निकालाची गणना न करता स्थानिक मोजणी चालू ठेवण्यासाठी हे आदेशांना एसिंक्रोनोली पाठविण्यास अनुमती देईल. जेव्हा आपल्याला device_1 वरील बॅचची गणना करण्याची आवश्यकता असते आणि device_2 वरील दुसर्‍या बॅचची गणना करणे प्रारंभ करण्यासाठी या गणनेची प्रतीक्षा करण्याची आवश्यकता नसते तेव्हा एक मोठा अनुप्रयोग असतो.

दूरस्थपणे योजना चालवा

आता आम्ही योजनेतील काही डेटा पॉईंटरवर कॉल करून रिमोट चालवू शकतो. ही योजना दूरस्थपणे चालविण्यासाठी कमांड जारी करते, जेणेकरून योजनेच्या आऊटपुटच्या पूर्वनिर्धारित ठिकाणी आता निकालाचा समावेश असेल (लक्षात ठेवा आम्ही गणना करण्यापूर्वी निकालाचे पूर्व-निर्धारित स्थान गमावतो). यासाठी एका संप्रेषणाची फेरी देखील आवश्यक आहे.

परिणाम फक्त एक पॉईंटर असतो, जेव्हा आपण सामान्य हुक torch फंक्शनला कॉल करता तेव्हा!


In [ ]:
pointer_to_result = pointer_plan(pointer_to_data)
print(pointer_to_result)

आणि आपण फक्त मूल्य परत विचारू शकता.


In [ ]:
pointer_to_result.get()

एका ठोस उदाहरणाच्या दिशेने

पण आपल्याला डीप अँड फेडरेटेड लर्निंगवर प्लॅन लागू करणे म्हणजे काय? तर आपण जरासे जटिल उदाहरण पाहू या, neural नेटवर्क वापरुन आपण कदाचित त्यांचा वापर करण्यास इच्छुक असाल तर. लक्षात घ्या की आपण आता क्लासचे योजनेमध्ये रूपांतर करीत आहोत. असे करण्यासाठी, आपण sy.Plan वरून आपल्या वर्गाचे वारस आहोत (nn.Module वरुन वारसाऐवजी).


In [ ]:
class Net(sy.Plan):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(2, 3)
        self.fc2 = nn.Linear(3, 2)

    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return F.log_softmax(x, dim=0)

In [ ]:
net = Net()

In [ ]:
net

चला काही मॉक डेटा वापरुन प्लॅन बनवूया.


In [ ]:
net.build(torch.tensor([1., 2.]))

आपण आता ही योजना दुर्गम कामगाराला पाठवित आहोत


In [ ]:
pointer_to_net = net.send(device_1)
pointer_to_net

चला काही दूरस्थ डेटा पुनर्प्राप्त करू


In [ ]:
pointer_to_data = device_1.search('input_data')[0]

तर सिंटॅक्स सामान्य रिमोट अनुक्रमिक एक्झिक्युशन प्रमाणेच असते, म्हणजेच स्थानिक एक्झिक्युशन. परंतु क्लासिक रिमोट एक्जीक्यूशनच्या तुलनेत, प्रत्येक एक्झिक्युशनसाठी एकच संप्रेषण फेरी असते.


In [ ]:
pointer_to_result = pointer_to_net(pointer_to_data)
pointer_to_result

आणि आपल्याला नेहमीप्रमाणेच निकाल मिळतो!


In [ ]:
pointer_to_result.get()

Et voilà! स्थानिक कामगार (किंवा सर्व्हर) आणि दूरस्थ उपकरणांमधील संवाद नाटकीयरित्या कसे कमी करावे हे आम्ही पाहिले आहे!

कामगारांन दरम्यान स्विच करा

आपल्याला पाहिजे असलेले एक प्रमुख वैशिष्ट्य म्हणजे अनेक कामगारांसाठी समान योजना वापरणे, आपण ज्या डेटाचा विचार करीत आहोत त्या दूरस्थ बॅचवर अवलंबून बदलू. विशेषतः, प्रत्येक वेळी कामगार बदलल्यास आपल्याला ही योजना पुन्हा तयार करायची नाही. आपल्या छोट्या नेटवर्कसह मागील उदाहरण वापरुन आपण हे कसे करतो ते पाहूया.


In [ ]:
class Net(sy.Plan):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(2, 3)
        self.fc2 = nn.Linear(3, 2)

    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return F.log_softmax(x, dim=0)

In [ ]:
net = Net()

# Build plan
net.build(torch.tensor([1., 2.]))

आपण नुकत्याच अंमलात आणलेल्या मुख्य चरणे येथे आहेत


In [ ]:
pointer_to_net_1 = net.send(device_1)
pointer_to_data = device_1.search('input_data')[0]
pointer_to_result = pointer_to_net_1(pointer_to_data)
pointer_to_result.get()

आणि प्रत्यक्षात आपण त्याच योजनेतून इतर पॉइंटरप्लान्स(PointerPlans) तयार करू शकता, जेणेकरून सिंटॅक्स दुसर्‍या डिव्हाइसवर दूरस्थपणे योजना चालविण्यासाठी समान असेल


In [ ]:
pointer_to_net_2 = net.send(device_2)
pointer_to_data = device_2.search('input_data')[0]
pointer_to_result = pointer_to_net_2(pointer_to_data)
pointer_to_result.get()

टीपः सध्या, योजना वर्गांसह आपण फक्त एक पद्धत वापरू शकता आणि आपल्याला त्यास "forward" असे नाव द्यावे लागेल.

कार्ये असलेल्या स्वयंचलितपणे योजना तयार करणे

फंक्शन्ससाठी (@ sy.func2plan) आपण स्वयंचलितपणे build कॉल करण्याची आवश्यकता नसलेली योजना स्वयंचलितपणे तयार करू शकतो, प्रत्यक्षात निर्मितीच्या क्षणी योजना आधीच तयार केली गेली आहे.

ही कार्यक्षमता साध्य करण्यासाठी जेव्हा एखादी योजना तयार करता तेव्हा आपल्याला एक गोष्ट बदलण्याची आवश्यकता असते ती म्हणजे args_shape नावाच्या decorator साठी एक argument सेट करणे, ज्यामध्ये प्रत्येक argument च्या आकारासह एक यादी असावी.


In [ ]:
@sy.func2plan(args_shape=[(-1, 1)])
def plan_double_abs(x):
    x = x + x
    x = torch.abs(x)
    return x

plan_double_abs.is_built

args_shape पॅरामीटर अंतर्गत आकारात मॉक टेन्सर तयार करण्यासाठी वापरला जातो जो प्लॅन तयार करण्यासाठी वापरला जातो.


In [ ]:
@sy.func2plan(args_shape=[(1, 2), (-1, 2)])
def plan_sum_abs(x, y):
    s = x + y
    return torch.abs(s)

plan_sum_abs.is_built

आपण कार्य करण्यासाठी state elements देखील प्रदान करू शकता!


In [ ]:
@sy.func2plan(args_shape=[(1,)], state=(torch.tensor([1]), ))
def plan_abs(x, state):
    bias, = state.read()
    x = x.abs()
    return x + bias

In [ ]:
pointer_plan = plan_abs.send(device_1)
x_ptr = torch.tensor([-1, 0]).send(device_1)
p = pointer_plan(x_ptr)
p.get()

याबद्दल अधिक जाणून घेण्यासाठी, आपण ट्यूटोरियल भाग 8 bis मध्ये प्रोटोकोल सह योजना कशा वापरता हे शोधू शकता!

Pysyft ला Github वर Star करा!

आमच्या समुदायाला मदत करण्याचा सर्वात सोपा मार्ग म्हणजे फक्त गिटहब(GitHub) रेपो(Repo) तारांकित(Star) करणे! हे आम्ही तयार करीत असलेल्या छान साधनांविषयी जागरूकता वाढविण्यास मदत करते.

GitHub वरील आमचे प्रशिक्षण निवडा.

आम्ही फेडरेटेड आणि गोपनीयता-संरक्षित लर्निंगबद्दल अधिक चांगल्या प्रकारे समजवण्यासाठी खरोखर चांगले ट्यूटोरियल बनवले आहेत.

आमच्या Slack मध्ये सामील व्हा!

नवीनतम प्रगतीवर अद्ययावत राहण्याचा उत्तम मार्ग म्हणजे आमच्या समुदायामध्ये सामील होणे! आपण http://slack.openmined.org येथे फॉर्म भरुन तसे करू शकता.

एका कोड प्रोजेक्टमध्ये सामील व्हा!

आमच्या समुदायामध्ये योगदानाचा उत्तम मार्ग म्हणजे कोड योगदानकर्ता बनणे! कोणत्याही वेळी आपण (PySyft GitHub Issues Page) वर जाऊ शकता आणि "Project" साठी फिल्टर करू शकता. हे आपण कोणत्या प्रकल्पांमध्ये सामील होऊ शकता याबद्दल विहंगावलोकन देणारी सर्व उच्च स्तरीय तिकिटे दर्शवेल! आपण एखाद्या प्रकल्पात सामील होऊ इच्छित नसल्यास, परंतु आपण थोडं कोडिंग करू इच्छित असाल तर आपण Good First Issue म्हणून चिन्हांकित गिटहब(GitHub) अंक शोधून आणखी "one off" मिनी-प्रकल्प(mini project) शोधू शकता.

दान करा

आपल्याकडे आमच्या कोडेबेसमध्ये योगदान देण्यास वेळ नसल्यास, परंतु तरीही आपल्याला समर्थन द्यावयाचे असल्यास आपण आमच्या मुक्त संग्रहात बॅकर देखील होऊ शकता. सर्व देणगी आमच्या वेब होस्टिंग आणि हॅकॅथॉन आणि मेटअप्स सारख्या इतर सामुदायिक खर्चाकडे जातात!

OpenMined's Open Collective Page


In [ ]: